What's new/changed in LLBLGen Pro Runtime Framework v5.10?
Below you'll find a list of changes, additions and important fixes in the 5.10 release of the LLBLGen Pro Runtime Framework. It's recommended you also browse the Migrating your code section for breaking changes and how to migrate your current project with generated code to v5.10.
What's new in LLBLGen Pro v5.10
Below you'll find what's been introduced in LLBLGen Pro Runtime Framework v5.10
New functionality / changes
- The framework now supports inserting entities directly based on a query. This is implemented using QuerySpec. More information: Adapter, SelfServicing
- Derived Model fetching now allows for additional where / orderby clauses to be specified for nested sets in the projection. More information (LLBLGen Pro part of the Derived Model documentation)
Small changes / fixes
-
We’ve added a global setting to
EntityBase
andEntityBase2
, ValidatePrecisionScaleSingleDoubleValues. This setting is true by default. When set to false, it’ll skip the precision/scale check inValidateValue
for float/double values and always allow them. This setting is true by default to prevent breaking changes, however it makes little sense to validate precision/scale on float/double values as they’re not precise (so precision/scale validation/checks shouldn’t be done) -
The
ObjectGraphTraverser
now distinguishesISortClause
objects and when traversingSortExpressions
it’ll call theTraverse
method forISortClause
objects. -
For inserts, a field-parameter pair is added to a dictionary, but the hashcode for field is using the hashcode of the value (plus the object
instance address). In v5.10 we changed this to only use the object address instance (
Object.GetHashCode()
) as it’s an unnecessarily expensive calculation as we just need to identity field objects. -
Linq: There’s now an
IQueryable.ToDictionaryAsync()
implementation to fetch a linq query into a dictionary asynchronously. TheToDictionaryAsync
method only accepts a keySelector func. There’s no overload to reproject the resultset. The main reason is that it’ll undo projection work of the main query so it’s always better to move the element selector/projector func to a select called prior to theToDictionaryMethod
. Soq.Select(projectorFunc).ToDictionaryAsync(keySelectorFunc);
instead ofq.ToDictionaryAsync(keySelectorFunc, projectorFunc);
as the latter is inefficient: it’ll allocate objects that are never used. -
All
DataReader.Read()
calls on async paths have been converted toDataReader.ReadAsync()
. This should give consistent exceptions when a task is cancelled. It might have some impact on runtime behavior as some ADO.NET providers might have edge cases which aren’t 100% efficient withReadAsync()
but are withRead()
. However the alternatives we have had for a long time aren’t without problems either so we’ve chosen to make this switch now.
What's new in LLBLGen Pro v5.9
Below you'll find what's been introduced in LLBLGen Pro Runtime Framework v5.9
New functionality / changes
- Ability to create a Linq query or QuerySpec query by wrapping a plain SQL query. Linq, QuerySpec
WITH TIES
support for queries with row limits set. Linq, QuerySpec- Firebird 4.0 support More information
- New .NET 6 specific IQueryable method implementations are added (ExceptBy/IntersectBy, First/Single/LastOrDefault with a default value specified, MaxBy/MinBy), as well as implementations of some IQueryable methods which were previously not supported (Last/LastOrDefault, Reverse) More information
- Derived Model projections: it's now possible to adjust generated projections in code. More information
- Arrays (one-dimensional) are now a supported type on PostgreSQL More information
- Runtime no longer creates dummy entity instances on the fly for query creation. Instead it now re-uses cached dummy entity instances, which should make query creation more efficient.
- The default compatibility level for the Oracle DQE using ODP.NET is now set to Oracle12c (which means Oracle 12c or higher).
- The default target platform for LLBLGen Pro is now .netstandard 2.1
-
The PostgreSQL and Oracle ODP.NET DQE's now have a static flag, available in the DynamicQueryEngine class:
AlwaysWrapFieldAliasesInDoubleQuotes
which is false by default, and which can be used to make the DQE always wrap aliases in double quotes, even ifCaseInsensitiveNames
is set to true. Use this to avoid having aliases which are reserved words to cause query failure whenCaseInsensitiveNames
is set to true.
Small changes / fixes
- Fixed: A linq query which results in a scalar query call loses any query hint specifications
What's new in LLBLGen Pro v5.8
Below you'll find what's been introduced in LLBLGen Pro Runtime Framework v5.8
New functionality / changes
- Dependency Injection support for other DI frameworks. It's now possible to use other dependency injection frameworks, like the one built-in into asp.net core, to inject validators, authorizers and the like into entities without any extra effort. More information
- The Default SQL Server compatibility level is now set to 2012.
- Json is now a supported type on Oracle databases. (Results in System.String)
- Alias names in queries for Firebird are now clamped to 30 characters to avoid the restriction that's been added to Firebird 3. This clamping is done by creating a unique alias, like what's been used on Oracle and DB2.
- It's now easier to extend the
TypeDefaultValue
class: a new partial method has been added which can be implemented in a partial class:PostProcessValueToReturn
. - QuerySpec now has extension methods to produce IExpression objects from fields, for the operations Mul, Div, Add, Sub, And, Or, BitwiseAnd, BitwiseOr, BitwiseXor, Mod.
- On Oracle the operators BitwiseAnd/Or/Xor are now supported in field expressions
- On Firebird stored procedures within packages are now supported
- On Firebird the system sequence
SQL$DEFAULT
is now supported - SelfServicing's
Transaction
class and Adapter'sDataAccessAdapter
class now have aCommitAsync
method. This is effectively the same as the synchronousCommit
method, however it will now persist audit entities asynchronously instead of synchronously. The Unit of Work'sCommitAsync()
method will call thisCommitAsync
method now as well. - Selfservicing specific: Two protected virtual methods are added to the EntityBase class:
OnSingleEntityLazyLoading
andOnMultiEntityLazyLoading
. These methods are called at the start of the lazy loading action and do nothing, but can be used to get notified when lazy loading occurs, e.g. for when tracking down lazy loading actions when migrating to Adapter or when optimization work is performed.
Small changes / fixes
- Fixed: When an entity has been deleted, it no longer ends up in an Update queue
What's new in LLBLGen Pro v5.7
Below you'll find what's been introduced in LLBLGen Pro Runtime Framework v5.7
New functionality / changes
- DTO Class models with QuerySpec. Starting with v5.7 you can now use QuerySpec to fetch derived models using the DTO Class model and the LLBLGen Pro Runtime Framework.
- Async call methods for stored procedures. Starting with v5.7, calling a stored procedure (Action, or Retrieval) will now be possible using native async methods, without using a workaround using QuerySpec.
- ESCAPE clause support for LIKE predicates. It's now possible to use escape clauses in LIKE predicates.
- IDictionary<string, object> support for parameters in Plain SQL queries. The Plain SQL api now supports parameter definitions using
IDictionary<string, object>
, which allows for dynamicly created Plain SQL queries and parameter values.
Small changes / fixes
- We've introduced the class ORMTraceSwitchNames which contains the names of the trace switches defined by the ORM Support classes. The properties return the names in string form of the trace switch with the same name. They can be used instead of a constant string with
RuntimeConfiguration.SetTraceLevel
. - Typed views mapped onto a stored procedure resultset and which have as output type PocoWithQuerySpecQuery will now get async variants generated of the call code in the
RetrievalProcedures
class, which makes it easier to fetch these typed views asynchronously. - (Adapter)
IDataAccessAdapter
and thereforeDataAccessAdapter
now have a property UseRecoveryStrategy which is true by default and which controls whether the actively set recovery strategy should be used (default, true) or not (false), in the query/queries to execute using the adapter. Use this property to execute one or more queries without using an automatically set recovery strategy. - (Adapter) executing a retrieval procedure to fetch data into a datatable/dataset now uses the built-in connection open/close mechanisms so custom code in a derived class to e.g. setup role usage on SQL Server now works properly.
- The open source library LLBLGen.Linq.Prefetch, with prefetch path extension methods for Linq has now been merged into the runtime. The namespace is the same, so all you have to do is remove the reference to the nuget package or if you use the source file, please remove the source file from your project. The nuget package was for .NET framework only and by merging it into the runtime it now also works on .NET Standard.
ITransaction
now derives fromIDisposable
- When the compiled lambda cache of a thread for Linq or QuerySpec reaches the maximum number of elements (by default 10000), it’s recycled and when this happens a trace message will now be written if the ORMQueryExecution trace switch has been set to info or verbose level. The trace switch message has the format: "Cache owner: the compiled lambda cache for thread threadid has been recycled on datetime in UTC UTC as it had reached maxNumberOfEntries entries." CacheOwner is either "Linq" or "QuerySpec".
What's new in LLBLGen Pro v5.6
Below you'll find what's been introduced in LLBLGen Pro Runtime Framework v5.6
New functionality / changes
- Better spatial types support. The runtime now also supports spatial types on PostgreSQL, on both .NET Framework and .NET Standard.
- Non-recursive graph traversal. The runtime will now use a breadth-first search algorithm when persisting an entity graph which avoids stack overflows in large, deep graphs. On top of that it's also 10% faster than the older one.
Small changes / fixes
- .NET Standard 2.1 is now a supported target platform.
- Prefetch paths fetching: If there’s just 1 root element and a limit was defined on a direct child element, the child element’s limit is now honored inside the database as all the child elements are for at most one parent.
- QuerySpec: Specifying a function call on a partition clause is now properly evaluated
- Empty resultsets are now cached, so executing the same query will pull the empty resultset from the cache instead of executing the query again.
- Target hint and Temporal Table predicates can now be specified on prefetch path nodes in Linq and QuerySpec.
What's new in LLBLGen Pro v5.5
Below you'll find what's been introduced in LLBLGen Pro Runtime Framework v5.5
New functionality / changes
- Insert / update query batching (Adapter). The runtime now supports batching of insert and update queries into single DbCommand objects which great helps with performance, especially when using a database over a connection with high latency, like a cloud database. Available for Adapter, on the databases SQL Server, PostgreSQL and Oracle. More information
- Window specification support (OVER() clause)). The LLBLGen Pro Runtime Framework now comes with support for the SQL
OVER()
clause, which is used with window functions. OVER() allows aggregates and specific window functions to define a window in the resultset. This support is two fold: existing aggregate functions can be extended with an OVER() clause in the SQL query and new window functions likeRANK()
andFIRST_VALUE()
are supported and can be specified directly in an LLBLGen Pro query together with an OVER() clause. More information. - Union / Union All support in Linq and QuerySpec. The LLBLGen Pro Runtime Framework finally gets support for a feature that has been requested
for many times: support for
UNION
andUNION ALL
in queries. For Linq, there's now full support for.Union()
and.Concat()
(the Linq equivalent for UNION ALL). For QuerySpec, the support comes in the form of two new methods:Union()
andUnionAll()
. More information: Linq, QuerySpec - Oracle is now supported on .NET Standard. Oracle has finally released a .NET Standard 2.0 compliant ADO.NET provider, and you can use the LLBLGen Pro Runtime Framework now with Oracle on .NET Standard supporting platforms like .NET Core 2.x. More information
- Function mappings of functions with no arguments for Linq. Mapping a function which has no arguments, e.g.
GetDate()
is now supported for Linq (QuerySpec already did support this). This allows you to map a .NET method which doesn't accept any database originating elements to a database function. More information - Query / Optimizer hints for Linq / QuerySpec. It's now possible to specify a query hint or optimizer hint to help a database optimizer with a choice to make when optimizing a given query. Available for SQL Server, Oracle and MySQL. More information Linq, QuerySpec.
Small changes
IEntityCollectionCore.Clear(bool)
has been added, where if the boolean argument is set to true, the entities in the collection are added to the RemovalEntitiesTracker collection of theIEntityCollectionCore
instance (if present).- An EntityView(2) no longer issues a Reset with the
ListChanged
event when a field of an entity in the view changes however it has no effect on the order of the entities in the view. It only issues a Reset with theListChanged
event if the order changed due to the change of the entity field. - The BooleanNumeric type converter now supports float and double values as well for boolean. This means that a conversion from boolean will result in 1.0 and a conversion to boolean will be using Convert.ToBoolean(value).
- An implicit conversion between Enum and string is now supported, besides the already supported implicit conversion between Enum and a numeric value (int/byte etc.). This means you can map an enum typed field onto a string based database field without a type converter. The conversion will use the ToString() method on the Enum instance to produce the string value when persisting an entity to the database.
- Implicit numeric conversions between fields of type byte, sbyte, short, int, long, float, double, decimal are now supported without a type converter.
- Introduced object name creation caching to avoid string concatenations which are repeated a lot of times per query. This both saves memory and some query creation performance.
- ISortClause now has two new command chaining methods:
SetCaseSensitiveCollation(bool)
andSetEmitAliasForExpressionAggregateField(bool)
which set resp. theCaseSensitiveCollation
andEmitAliasForExpressionAggregateField
flags and return theISortClause
instance again for command chaining. ISortClause
andISortExpression
now have an extension methodThenBy()
which accepts anISortClause
and which is appended to the object it's called on. TheThenBy()
method is in the QuerySpec namespace.- The Oracle DQEs for ODP.NET and MS Oracle now have a static flag,
DynamicQueryEngine.AlwaysUseRowNumBasedPaging
, which is set to false by default. If true, and compatibility is set to 12c, a paging query will use the classic rownum approach instead of the FETCH NEXT / OFFSET approach. The latter can be up to 40 times slower than the rownum approach (see: the JOOQ blog) so the classic rownum approach might be more efficient in your application than the new approach. - The Firebird DQE now has function mappings for DateTime properties Year, Month, Day, Hour, Minute, Second, MilliSecond, DayOfYear, DayOfWeek and the DateTime methods AddYears, AddMonths, AddDays, AddHours, AddMinutes, AddSeconds, AddMilliSeconds.
- When a retrieval query is forced to perform client side paging, distinct filtering or limiting, it will now append resp. "Requires client side paging", "Requires client side distinct filtering" or "Requires client side limiting" when the ORMQueryExecution tracer is enabled and the level is set to 'verbose' (4).
What's new in LLBLGen Pro v5.4
Below you'll find what's been introduced in LLBLGen Pro Runtime Framework v5.4
New functionality / changes
- Generated code is now much smaller, especially for Adapter. This leads to faster compilation times and faster code generation times (on top of the faster
code generator in v5.4). A lot of code has been moved to the base classes
EntityBase
andEntityBase2
. These changes have no negative memory impact nor performance impact, in fact memory consumption in prefetch paths is slightly better now. - The PlainSQL API now has a feature to perform implicit conversions of types, meaning a value of type T1 in the resultset can be implicitly converted to type T2 in the projection class, if an implicit conversion is defined for T1 and T2 (e.g. short to int)
- Poco Typed List fetch methods in Linq and QuerySpec now have an optional query argument to be used as the root query, allowing you to specify a richer query than the generated query for the typed list.
- PostgreSQL 10.x is now a supported database, which includes support for the new Identity fields in PostgreSQL 10.x
- Empty methods for Field-mapped-onto-related-field event handlers are now avoided and code is less verbose
- UnitOfWork and UnitOfWork2 now have a property
IsEmpty
which returns true if no work is scheduled in the unit of work instance. This property is also implemented in the interfaceIUnitOfWorkCore
. - PostgreSql: the query generated for directly deleting entities using a join with another table now no longer uses non-ansi joins but uses a proper ansi-join using correlated subquery.
- When fetching prefetch paths with a paging query, the runtime now automatically switches over to parametrized IN clauses for the prefetch path sub paths, no matter the value for the
ParameterizedPrefetchPathThreshold
. This avoids that all rows in the target of a sub path node are fetched and filtered on the client. This is now also done if a limit is specified for the root node and no paging is performed, the runtime in that situation now also picks the parameterized route.
It can lead to a crash if the page is too large, and too much parameters are issued for the sub path query. This is equal to the user setting the ParameterizedPrefetchPathThreshold
to a value higher than the maximum amount of parameters allowed by the database. The solution to this is to use a smaller page size so the # of elements in a page is smaller than the max number of parameters for a database.
- The PostgreSQL DQE now uses the
RETURNING
clause to return sequenced fields in an insert query instead of a separate scalar query which used a separate roundtrip; each insert query is always one roundtrip, even if there are sequenced fields involved. - SelfServicing:
DeleteMulti
/UpdateMulti
and async variants are now virtual. - Using
FetchProjection<T>(retrievalQuery)
orFetchQuery<T>(plainSqlString)
where T is a valuetype likeInt32
or a system type likestring
, the query would fail in previous versions but will now succeed with returning a list of values (the values of the first column in the resultset), all typed T.
What's new in LLBLGen Pro v5.3
Below you'll find what's been introduced in LLBLGen Pro Runtime Framework v5.3
New functionality / changes
- .NET Standard 2.0 support. The LLBLGen Pro Runtime Framework can now be used on .NET Standard 2.0 supporting platforms like .NET Core 2.0 and Xamarin. Please see the .NET Standard support page for details regarding the small amount of limitations you might run into.
- New RuntimeConfiguration system to configure LLBLGen Pro Runtime Framework specific behavior and settings in code instead of in .config files. Mainly meant for .NET Standard 2.0 using applications but it's also available for .NET Framework.
- The Plain SQL API now has a
FetchScalarQuery<T>
method to retrieve a scalar value from the DB using a plain SQL query. More information. - Query tagging. Linq and QuerySpec have the ability now to let you mark (tag) the SQL query or queries generated by the runtime with a tag. This tag is a string which is added as a comment before the actual query string. This way you can easily track back the SQL query on a database server with the actual calling code without a profiler / stacktrace. It's a low-impact way to make sure you can track down information at runtime in the future. More information: Linq, QuerySpec.
Small changes
- The Runtime Framework is now compiled against .NET 4.5.2
- QuerySpec: When a scalar query is executed using
FetchScalar<T>
and T isn't a nullable type and the query returns a NULL value, the cast to T would result in a Null reference exception. We now added a check first which will throw an InvalidOperationException if a null value was returned and the type specified isn't a nullable type. - Lambda caches and factory caches are now using a ConcurrentDictionary instead of a Dictionary per thread, which should save some memory in large applications.
- QuerySpec: an extension method has been added for ISortClause,
DontEmitAliasForExpressionAggregateField
, so the EmitAliasForExpressionAggregateField flag can be set using the fluent interface. See the LLBLGen Pro Runtime Framework Reference Manual for details. - A new exception class has been added:
ORMConfigurationException
. This exception is thrown when an error is detected in the RuntimeConfiguration usage. - Prefetch path fetches with a context are now using faster merges as the linear searches caused by the context usage in collections during merges are now no longer happening. This is done when the fetch is into a new graph. An existing graph will do the linear searches during merge as before.
- Nuget: the packages for DQEs now reference a specific ORMSupportClasses version, which means you always have to update both when referencing a specific DQE package version. Previously we defined a range of
[currentversion-nextmajorversion)
but that is too large and causes 'downgrades' for .NET Core due to a change in the way downgrade warnings are handled by the .NET Core tooling. - Field compare value predicate now detects value truncation for variable string typed parameters. If it detects truncation, it will emit "1=0" instead of the actual predicate, followed by a comment to make the predicate result in 0 rows. Value truncation occurs if the DbParameter's Value property is set to a value which has a length longer than the 'size' property. The size property of the parameter is set to the length of the field compared against. So if you compare a varchar(20) typed field F to a string with length 25, you'll get 1=0 instead of the comparison of the first 20 chars of the string with the field, which could lead to matches which are unintentional.
- Field value equality comparisons of byte array values are now more optimal.
- Firebird 3.0 support. LLBLGen Pro Runtime Framework now supports Firebird 3.0. This effectively means that the new Boolean type is now fully recognized. The identity field support of Firebird 3.0 will be added as soon as the Firebird Client supports this.
What's new in LLBLGen Pro v5.2
Below you'll find what's been introduced in LLBLGen Pro Runtime Framework v5.2
New functionality / changes
- Data Scope now has Async / Await variants of its methods so it can be used fully asynchronously.
- A global flag has been added for SelfServicing to disable lazy loading with one setting:
EntityBase.EnableLazyLoading
. The flag is enabled by default (so lazy loading is enabled by default) for backwards compatibility. - Lots of string interpolation has been refactored to more efficient string usage, resulting in faster performance overall and even lower memory footprint/object pressure. LLBLGen Pro is now the fastest ORM, beating all microORMs too (using the plain sql API).
- Size specification on
Init()
methods in the generatedFieldInfoProvider
andPersistenceInfoProvider
classes have been removed, so merge conflicts will no longer occur when merging different code bases of generated code. - For new projects and projects which change the target framework to the LLBLGen Pro Runtime Framework, the default output type for TypedLists and TypedViews has been changed to PocoWithQuerySpecQuery. This was TypedDataTable. If you still want to use TypedDataTable as the outputtype for TypedLists and TypedViews, you can change the default in the LLBLGen Pro Runtime Framework settings in the Project Settings. The default choice is for QuerySpec and not Linq because typed views mapped onto stored procedure resultsets aren't supported in Linq but are supported with QuerySpec. For existing projects the old default is kept.
- Linq/QuerySpec: Using 'Distinct' on a subquery which is used inside an 'IN()' clause is now used inside the subquery. This is due to an addition in the FieldCompareSetPredicate which now allows 'Distinct' in the subquery. For most databases the 'Distinct' in the subquery has no effect, but on e.g. Oracle it can help the optimizer to pick an index instead of doing a table scan.
AddCollectionForSave
andAddCollectionForDelete
are now part ofIUnitOfWorkCore
.DataAccessAdapter.SaveTransaction(name)
andTransaction.SaveTransaction(name)
no longer throw an exception whenname
was already used within the same transaction, as all supported databases which do support savepoints support multiple savepoints with the same name in a single transaction so the check / limitation is unnecessary.- Entity field validation now doesn't report a precision overflow for decimals/floats/doubles with precision equal to scale and a value between (-1.0, 1.0) excluded. Even though the precision of a value in that interval, e.g.
0.55
, is 3, the leading zero isn't taken into account by databases and therefore the runtime shouldn't either.
What's new in LLBLGen Pro v5.1
Below you'll find what's been introduced in LLBLGen Pro Runtime Framework v5.1
New functionality / changes
QuerySpec
- Easier projection definitions. It's now easier to define a projection to a POCO when you want to specify a set of fields in a Select. More information: Projections in QuerySpec
General
- Temporal (History) Table support:. For SQL Server 2016 and higher/ DB2, temporal tables are now supported through Linq / QuerySpec (Select / fetch queries only). Temporal tables are an easy, friction free way to store previous versions of modified / deleted rows in a table. The temporal table support in LLBLGen Pro allows you to include older versions of entities when querying. More information: Linq, QuerySpec
- Hints support. For SQL Server / MySQL, select target hints are now supported through Linq and QuerySpec. More information: Linq, QuerySpec
- Plain SQL API. You can now execute plain SQL statements using parameters directly onto the database, including fetching resultsets and projecting the resultsets to POCO classes. With this API you don't need a microORM on the side anymore for those situations where the runtime couldn't give you the right query. This API is also very fast: fetching a query through this API is faster than most microORMs. See: Results from 21 September 2016. These results were determined using RawDataAccessBencher. More information: Plain SQL API.
- Easier projections from stored procedures. It's now easier to create projections of stored procedure resultsets onto POCO classes, all it takes is specifying the target type. More information: Adapter, SelfServicing
What's new in LLBLGen Pro v5.0
Below you'll find what's been introduced in LLBLGen Pro Runtime Framework v5.0
New functionality / changes
- Linq: It's now possible to use
Union()
in the last projection in the query (the most outer projection). TheUnion()
call is not executed in the database but in the projection code itself. UsingUnion()
elsewhere in the query will still lead to an error asUnion()
isn't supported in LLBLGen Pro queries. IDataAccessAdapter.KeepTrackOfTransactionParticipants
has been added. The flag (default true) is used to signal the adapter that entities participating in a transaction controlled by this adapter are tracked during the transaction and which values are rolled back after a rollback of the transaction itself. Only set this flag to false if the entities participating in a transaction are not kept in memory during or after the transaction's life time.- Queries using projections in Linq or QuerySpec are now 30-40% faster than in v4.2 and are in general faster than a lot of the existing MicroORMs. See: https://github.com/FransBouma/RawDataAccessBencher, results from December 16th, 2015.
-
QuerySpec now defines a CaseInsensitive extension method for FieldCompareValuePredicate to set it into CaseInsensitive mode:
IPredicate p = CustomerFields.CompanyName.Equal("Foo Inc").CaseInsensitive();
-
QuerySpec now defines a CaseInsensitive extension method for
ISortClause
to set it into CaseInsensitive mode:ISortClause s = CustomerFields.CompanyName.Descending().CaseInsensitive();
- Various changes in the Linq provider to make it more robust.
- The static variable
EntityCore.MakeSettingNonNullableFieldsToNullFatal
has been added (default: false, for backwards compatibility), to make setting a non-nullable field to null throw anArgumentOutOfRangeException
. - SQL Server 2016 is now a supported database (through the SQL Server DQE/templates). Use 2012 compatibility to utilize the 2012 or higher features.
What's new in LLBLGen Pro v4.2
Below you'll find what's been introduced in LLBLGen Pro Runtime Framework v4.2
New functionality / changes
General
- Allowed Action Combinations: Specify which actions are allowed on an entity instance: Any combination of Create/Read/Update/Delete. Action Combinations make it easy to define e.g. entities which can only be created or read but never updated nor deleted. The action combinations are defined at the mapping level and checked inside the runtime and are additional to the authorization framework. More information...
- Expression support during Inserts It's now possible to define an expression on an entity field which is used during inserts. The expression defined is used to produce the field value. More information...
- Generate Typed Lists as POCO classes with a Linq or QuerySpec query. It's now possible to generate a typed list or all typed lists (controllable through settings) as a simple POCO class which holds the data of a row in the resultset and a Linq or QuerySpec query to execute the typed list. Adapter, SelfServicing
- Generate Typed Views as POCO classes and use them in Linq and QuerySpec. It's now possible to generate a typed view or all typed views (controllable through settings) as a simple POCO class and use it in Linq or QuerySpec queries. Adapter, SelfServicing
- Transparent Transient Error Recovery (adapter only). The transient error recovery system introduced in v4.1 has been upgraded so it can now be used transparently: define once and it is automatically used when executing a query. It's no longer necessary to explicitly execute a query through a recovery strategy. More information...
- Cached resultset tagging for easy cache purge/retrieval It's now possible to tag a query's resultset if that resultset is cached so the resultset can be retrieved from the cache using the tag and also it's now possible to purge the resultset(s) associated with the tag from the cache. More information...
- Exclude prefetch path nodes from resultset caching. It's now possible to exclude a prefetch path node from being cached if the root query has a resultset caching directive. More information...
Small changes / fixes
-
QuerySpec: Multiple calls to
query.From(operand)
are now appending the operand to the existing From clause if operand starts withQueryTarget
. If it doesn't start withQueryTarget
and there's an existingFrom
clause, it will overwrite the existingFrom
clause. -
OData: The OData Support Classes now support the
IgnorePropertiesAttribute
on entity classes. The names specified using the attribute have to be defined on the entity type the attribute is defined on, so inherited properties can't be filtered out using this attribute. - Low level api: Duplicate sort clauses are now filtered out so accidentally added duplicates through e.g. OData are no longer causing exceptions at runtime.
-
Dynamic Query Engines: when the source of a field isn't known, the
field creator functionality will no longer emit a dangling
.
but will simply only emit the field name/alias. This way constucts like.OrderBy("Name".Ascending())
will work, where the engine will emitORDER BY [Name] ASC
. Previously the above construct would result inORDER BY .[Name] ASC
which would fail. -
Query traces: The value of a parameter of type
DateTime
value in a query is now emited as a ISO 8601 / Roundtrip formatted string, which is more precise than the previousToString()
call on theDateTime
which didn't include fractions of a second. -
FunctionMappings added
(Linq/QuerySpec):
sbyte/byte/ushort/short/uint/int/ulong/long.ToString()
mappings have been added to all DQEs for all databases. -
EntityBase(2).AllowReadsFromDeletedEntities
allows code to read from an entity that has been marked as deleted. It's been set to 'false' as the default which will result in an exception if code reads from a deleted entity, like in previous versions. - SQL Server 2014 is now a supported database (through the SQL Server DQE/templates). Use 2012 compatibility to utilize the 2012 or higher features.
- Catalog name is now supported in sequence name, if applicable. In SQL Server, a catalog name can be present in the sequence name, and should be overwritten if required. In previous versions, the catalog name was ignored, only schema names were supported with a sequence name.
- FIX: QuerySpec: A projection lambda was created using a parameter which was created for every new query, which resulted in a new cache key for the lambda so the lambda was compiled every time instead of re-using a cached version. The lambda is now created using the same parameter as the original and the compiled version cached is re-used in subsequential executions of the same projection so query creation is a bit quicker.
-
FIX: QuerySpec: QuerySpec doesn't properly replace function mappings in derived tables. Queries like the following now work:
var qf = new QueryFactory(); var qs = qf.Create("S") .Select(DateTimeFunctions.Year(OrderFields.OrderDate).As("YearOrder")); var q = qf.Create() .Select(qf.Field("S", "YearOrder")) .From(qs);
-
QuerySpec: There's now a class available to create a projection
lambda quickly for
Select<T>()
calls, calledProjectionLambdaCreator
. This class has two overloads of itsCreate()
method which creates at runtime a projection lambda for T from either a specified fields set or a fields creation class (e.g.CustomerFields
). The overload which accepts the fields creation class caches the created lambda and is therefore much faster than a lambda created in code and compiled by the C# / VB.NET compiler which will create a newExpression<Func<T>>
at runtime each time it is run.
Usage:
Here, thevar qf = new QueryFactory(); var q = qf.Create() .Select(ProjectionLambdaCreator.Create<OrderPocoQsRow, OrderPocoQsFields>()) .Where(OrderPocoQsFields.CustomerId == "ALFKI");
ProjectionLambdaCreator
creates a lambda for theOrderPocoQsRow
, which is equal to the code below which was what you had to write in v4.1 and earlier:
The advantage is that the// equivalent code, prior v4.2 //... .Select(() => new NW26.Adapter.TypedViewClasses.OrderPocoQsRow() { CustomerId = OrderPocoQsFields.CustomerId.ToValue<System.String>(), EmployeeId = OrderPocoQsFields.EmployeeId.ToValue<Nullable<System.Int32>>(), Freight = OrderPocoQsFields.Freight.ToValue<Nullable<System.Decimal>>(), // etc. all fields specified. }) //..
ProjectionLambdaCreator
call caches its lambda under the two types specified while the written out lambda creation code will create a new one each time it is run. Running the code about 100,000 times takes 98ms for theProjectionLambdaCreator
and 19832ms for the written out code, so it does make a difference. -
QuerQuerySpec: There's now a special
Select
method available which produces its own lambda projector from two types given:
This method,var qf = new QueryFactory(); var q = qf.Create.Select<SomeDTO, SomeElementFields>();
dynamicQuery.Select<T, U>()
creates a projection and projector lambda fromT
andU
fordynamicQuery
and makes it aDynamicQuery<T>
. The typeT
is the type of a class which instances are returned by the createdDynamicQuery<T>
, and can be an entity type or DTO or e.g. generated typed view type. The typeU
is the type of the generated helper class which creates the fields forT
, e.g.CustomerFields
. -
QuerySpec: The usage of
QueryTarget
is now also supported inDynamicQuery / DynamicQuery<T>
instances, but only in appending join operands to an existing query:var q = qf.Create() .From(qf.Customer.InnerJoin(qf.Order) .On(CustomerFields.CustomerId.Equal(OrderFields.CustomerId))); //.... q.From(QueryTarget.InnerJoin(qf.OrderDetails) .On(OrderFields.OrderID.Equal(OrderDetailFields.OrderId)));
-
QuerySpec. you don't need to create a new field for each targeted
subquery field anymore, if you want to effectively clone the
projection of a subquery. It's now possible to clone a projection of
a derived table/aliased subquery in an outer query's
Select()
method. - It's now possible to generate case insensitive SQL for case sensitive databases using a setting.
What's new in LLBLGen Pro v4.1
Below you'll find what's been introduced in LLBLGen Pro Runtime Framework v4.1
New functionality / changes
General
- Full async API. The runtime framework now offers a full Async API, usable in Linq, QuerySpec and the Low-Level API for retrieval of data and object persistence. Usable in async/await code on .NET 4.5 and higher. More information...
- Transient Error Recovery The runtime framework now offers the ability to recover from transient errors occuring during database activity. More information...
-
Oracle 12c support The runtime now supports Oracle 12c:
Identity/default sequences are now supported on Oracle 12c as well
as the new paging keywords for
SELECT
on Oracle 12c. - Managed Oracle ODP.NET provider support The runtime now supports the managed ODP.NET provider for Oracle (v12+ of ODP.NET).
Changed
- The default for the designer setting TdlEmitTimeDateInOutputFiles has been changed to false.
-
LinqMetaData now has an overload of
GetQueryableForEntity
:GetQueryableForEntity<TEntity>()
, which accepts a generic type and returns aDataSource
(2) object for the given entity type. -
If a sequence retrieval query(fragment) returns null before/after an
insert, due to wrong sequence semantics or the field isn't marked as
identity in the database while the mapping code defines it as a
sequenced field, an exception of type
ORMBadSequenceException
is now thrown. The exception contains the query executed. -
CachingController
now has a static public field,CachingEnabled
(default true), which controls whether the caching controller caches resultsets (true, default), or silently doesn't cache any resultsets (false). Useful when debugging code which otherwise would cache the resultset. -
To QuerySpec the fluent extension method
IEntityRelation.SetCustomFilter
(..) (2 overloads) has been added to easily set a custom filter on a relation specified in a queryspec query. This extension method, as most QuerySpec extension methods, is also usable with the low-level API. -
Adapter now has a new method on entities:
DetachFromGraph
. This method will detach the entity it's called on from its referenced entities, including m:n relations. It will only dereference from the entities it knows of at runtime. -
BREAKING CHANGE:
Multiple
.Take()
calls on a query in Linq will no longer result in 'last Take wins' but will use the lowest number of theTake
calls. - BREAKING CHANGE:OData Support Classes are now build against WCF Data Services 5.6.0.
What's new in LLBLGen Pro v4.0
Below you'll find what's been introduced in LLBLGen Pro Runtime Framework v4.0
New functionality / changes
General
- 50% faster entity fetches. An extensive refactoring of the internal storage of values inside an entity instance resulted in up to 50% faster entity fetches. As entity instances don't have Entity Field instances to store their values anymore (though from the outside it will appear they will, so no code will break), memory footprints are smaller too. See http://pastebin.com/AdsKitr3 for a benchmark of how much faster the fetches are compared to v3.5 and other ORMs.
- Extensible Query Result Caching. It's now possible to specify (in Linq or QuerySpec, and with minor effort also with low-level API calls) a query result cache directive to tell the runtime to cache the results for that particular query for a given amount of time. The caching system is build around an easy interface, making it easy to extend it with own cache providers for cache systems like Redis. More information...
- Table Valued Function support. It's now possible, using Linq and QuerySpec, to fetch entities and typed views which are mapped onto a table valued function resultset. Linq, QuerySpec
- DataScopes. The runtime framework now offers DataScopes which greatly help managing data in memory in desktop applications. More information...
- Runtime Libraries are now compiled against .NET 3.5. The minimum .NET version supported by the runtime framework is now .NET 3.5.
- LinqSupportClasses and QuerySpec assemblies are now merged into ORMSupportClasses. The 3 assemblies are now merged into one, SD.LLBLGen.Pro.ORMSupportClasses.dll. This makes referencing assemblies simpler.
- Inlining of Value Type Definitions in the designer. It's now possible to in-line value type definitions in the designer, which makes modeling LLBLGen Pro projects simpler. More information...
- SQL Server 2012 sequences support The runtime framework now supports SQL Server 2012 sequences in insert queries.
- TypedLists can now be fetched using QuerySpec. Before, the low-level API had to be used to fetch typedlists. In v4.0 we made it possible to fetch TypedLists using the more powerful QuerySpec query API.
-
True skip/offset support. It's now possible to skip n rows in a
fetch without the requirement that the number of rows fetched is a
multiply of n. This is in line with how Skip works in Linq.
QuerySpec now has a new operator,
Offset(n)
which offers the same functionality. -
Char <-> String(1) built-in type converter. The runtime
framework now has a built-in type conversion for
char
<->string(1)
, to make it possible to have a DB field of typechar(1)
be used as a .NET char typed field. - Support for OData v3. The ODataSupportClasses now support OData v3 and are now compiled against WCF Data Services v5.3.
- QueryExecution Tracer. A new tracer has been added, to trace the actual query being executed. This information was already available through other tracers, but as these also emitted other information it could lead to a lot of data just to see which query was actually executed. This tracer solves that.
- All low-level query API elements, including UnitofWork2, are now XML Serializable. All low-level query API classes, like predicates, relation collection, groupby collection but also the Unit of Work classes, are now serializable to XML, and as such passable to e.g. a WCF Service. This is for Adapter only.
Changed
- SourceFieldFinder. The SourceFieldFinder is now a public class so it can be used to traverse entity graphs in user code.
- Better name length clamping in DB2 and Oracle DQEs. Names were already limited to 30 characters or less for DB2 and Oracle, but in some edge case queries with nested derived tables it could be the field inside a derived table was clamped to a shorter name, but a field referencing it wasn't. Name clamping now uses F__hashcodeOfStringToClamp which is not depending on field index anymore.
- The runtime assemblies are now stored all in one folder. In previous versions the runtime library assemblies were stored in different folders, based on the .net version they were for. This is not needed anymore, so all files are stored in one folder.
- DbCommands are now, when possible, created from DbConnection. This makes it easier to add functionality like the miniprofiler to the generated code.
- DataProjectorToDataTable now creates columns from projectors. This change has the advantage that if the resultset to project has 0 rows, the columns in the datatable are still created.
Fixed
- Add auto-type filter if projection contains fields of 1 type only. See: http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=21502
- IRetrievalQuery requires a flag to signal no name overwriting required. See: http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=21658&StartAtMessage=0
- ObjectGraphUtils uses GetMemberEntityCollections which triggers collection creation on adapter. It now uses less intrusive methods, so it doesn't trigger collection creation.